
/**
 * Kernel Monkeys
 * Andrew Boguk
 * Sergiy Kulyk
 * Nicholas Swartzendruber
 */

/*
 *  process.h
 *
 *  Created on: May 15, 2011
 *  Author: Sergiy Kulyk
 */

#ifndef PROCESS_H_
#define PROCESS_H_



/*******************************************************************
 *              Request                                                                                                    *
 ******************************************************************/

#define NUM_REQ_TYPE 2

/**
 * Type of the requests processes can ask for.
 */
enum request_type_t {
    IO,
    SYS
} request_type_t;


/**
 * Request information.
 */
typedef struct req {
    int    step;        // step number on which this request should occur
    enum request_type_t type;   // request type

} request_t;


/**
 * Request type constructor.
 */
request_t * request_new(const int step,
                        const enum request_type_t type);



/*******************************************************************
 *              Process                                                                                                    *
 ******************************************************************/

/**
 * A unit of "work" the process is to perform.
 * This number actually represents time in microseconds
 * a process will spend sleeping, imitating work.
 */
#define WORK_UNIT 1000
#define NUM_PROC_TYPES 3

/**
 * Process data.
 */
typedef struct p_str {
        int             id;     // process id
    int         num_steps;      // number of "instructions" to run (before resetting to 0)
    int         num_requests;   // number of requests generated during one full run
    enum process_type_t {
        CALCULATING,
        PRODUCER,
        CONSUMER
    }   process_type;   // type of the process
    request_t** req_type; // array of request types. It is expanded to the
                                                // required size in the process constructor.
} process_t;


/**
 * Process constructor. Returns a pointer to a new process record, or
 * a null pointer if it was unable to obtain memory for it.
 *
 * @param id Process ID.
 * @param steps Number of "work" steps in one loop, before it starts repeating.
 * @param num_req Number of I/O requests this process will make during one loop.
 * @param req Array or pointers to requests. Pointer values will be copied
 *            inside the constructor.
 * @param p_type Type of the process.
 * @return Pointer to a new process.
 */
process_t* process_new(const int id,
                               const int steps,
                       const int num_req,
                       request_t** req,
                       enum process_type_t p_type);


/**
 * Process destructor. Frees the memory and sets the pointer to NULL.
 *
 * @param process Pointer to the process to be deleted. After the process is
 *                deleted, this pointer will be set to Null. *
 * @return Error code:
 *                      0: everything went well;
 *                      1: pointer is null;
 *                      2: other error.
 */
int process_delete(process_t* process);


/**
 * Run the process. This function will "run" the process until it gets to the
 * first I/O request. Then it stops and returns the next step value, also
 * the provided request to an appropriate type. The next time this process
 * is run, it should be given the "next step" value it returned last time (so
 * it should be stored somewhere externally, like a PCB record).
 *
 * @param process Process pointer.
 * @param next_step Next step to run.
 * @param request Request type.
 * @return Step to start from at the next run.
 */
int process_run(const process_t * process,
                        int next_step,
                        enum request_type_t * request);


#endif /* PROCESS_H_ */
